package JUC.第02章_Future;

import java.util.concurrent.*;

/**
 * 使用Future之前提供的那点API就囊中羞涩，处理起来不够优雅，
 * 这时候还是让CompletableFuture以声明式的方式优雅的处理这些需求
 *
 * 阻塞的方式和异步编程的设计理念相违背，而轮询的方式会耗费无谓的CPU资源。
 * 因此，JDK8设计出CompletableFuture。
 *
 * CompletableFuture implements Future<T>, CompletionStage<T>
 *  Future  老的
 *  CompletionStage  一堆方法
 *
 * CompletableFuture底层默认使用 ForkJoinPool   分支合并池子
 *
 * 从Java8开始引入了CompletableFuture, 它是Future的功能增强版，减少阻塞和轮询
 * 可以传入回调对象，当异步任务完成或者发生异常时，自动调用回调对象的回调方法
 *
 */
public class D2_CompletableFuture的异常处理 { //可以执行复杂的异步任务
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(5);//固定线程

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int result = ThreadLocalRandom.current().nextInt(10);//随机获取[0-9]
            try {TimeUnit.MILLISECONDS.sleep(1000); }catch (Exception e){e.printStackTrace();}
            if(result < 5) result = 10/0;//随机异常
            return result;
        },executorService);

        CompletableFuture<Integer> exceptionally =
                integerCompletableFuture.whenComplete((t, u) -> {
                    System.out.println("****t\t" + t);//null   因为出异常了  这个return没有执行   如果没异常t==返回的值
                    System.out.println("****u\t" + u);//返回异常信息  没异常  返回null
                }).exceptionally(f -> {//异常处理
                    System.out.println("excpyion\t" + f.getMessage());
                    //excpyion	java.lang.ArithmeticException: / by zero
                    return 4444;//重新定义一个返回值
                });

        System.out.println("main线程忙其他的");//会发现没有打印出结果
        //因为CompletableFuture 底层默认使用 ForkJoinPool  默认的线程池是守护线程
        System.out.println(exceptionally.join());//获取 CompletableFuture的返回值  不主动抛异常
//        System.out.println(exceptionally.get());//获取 CompletableFuture的返回值 主动抛异常

        executorService.shutdown();//关闭线程池
    }
}
